home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / gus / vts139b.zip / VTPLAY.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-22  |  22KB  |  831 lines

  1. UNIT VTPlay;
  2.  
  3. INTERFACE
  4.  
  5. USES VTGlobal, VTWins, VTStrConst, StrConst,
  6.      SongUnit, SongElements, PlayMod,
  7.      SoundDevices,
  8.      Output43, vid43,
  9.      Filters, Debugging;
  10.  
  11.  
  12.  
  13.  
  14. {----------------------------------------------------------------------------}
  15. { Definiciones generales                                                     }
  16. {____________________________________________________________________________}
  17.  
  18. PROCEDURE InitPlayData(VAR Song: TSong);
  19.  
  20.  
  21.  
  22.  
  23. {----------------------------------------------------------------------------}
  24. { Definiciones para la ventana de información de posición.                   }
  25. {____________________________________________________________________________}
  26.  
  27. VAR
  28.   LastFilterOn,
  29.   LastFilterOff : TFilterMethod;
  30.   LastFilter    : BOOLEAN;
  31.  
  32. PROCEDURE UpdateRunInfo(BPM, spd, patt, pos, seq, PSize: WORD);
  33.  
  34.  
  35.  
  36.  
  37. {----------------------------------------------------------------------------}
  38. { Definiciones para las barras de vúmetros.                                  }
  39. {____________________________________________________________________________}
  40.  
  41. VAR
  42.   barlen         : ARRAY[1..MaxChannels] OF BYTE;
  43.   obarlen        : ARRAY[1..MaxChannels] OF BYTE;
  44.   barofs         : ARRAY[1..16]          OF WORD;
  45.  
  46. PROCEDURE UpdateBars;
  47.  
  48. PROCEDURE ParseBarInit(VAR nt: TFullNote; i: WORD);
  49.  
  50.  
  51.  
  52.  
  53. {----------------------------------------------------------------------------}
  54. { Definiciones para las ventanas de información de notas.                    }
  55. {____________________________________________________________________________}
  56.  
  57. VAR
  58.   SampleStrings : ARRAY[1..99] OF STRING[24];
  59.   VolumeStrings : ARRAY[0..64] OF STRING[2];
  60.  
  61.   DispVolumes   : ARRAY[1..MaxChannels] OF BYTE;
  62.   DispNotes     : ARRAY[1..MaxChannels] OF TFullNote;
  63.   RealVolumes   : ARRAY[1..MaxChannels] OF BYTE;
  64.   RealNotes     : ARRAY[1..MaxChannels] OF TFullNote;
  65.  
  66.   DispSplName   : ARRAY[1..MaxChannels] OF BYTE;
  67.  
  68. PROCEDURE UpdateNoteInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  69.  
  70. PROCEDURE Update2ndLine(VAR Song: TSong; NewNote: BOOLEAN);
  71.  
  72.  
  73.  
  74.  
  75. {----------------------------------------------------------------------------}
  76. { Definiciones para las ventanas de información de samples.                  }
  77. {____________________________________________________________________________}
  78.  
  79. VAR
  80.   DispSamples   : ARRAY[1..99] OF BYTE;
  81.   RealSamples   : ARRAY[1..99] OF BYTE;
  82.  
  83.   siPermiso     : BOOLEAN;                  { Sample information }
  84.   siTickForce   : BOOLEAN;
  85.   siCounter     : BYTE;
  86.  
  87. CONST
  88.   sfNoSample = 0;
  89.   sfNotUsed  = 1;
  90.   sfUsed     = 2;
  91.   sfNowUsed  = 3;
  92.   sfFlashing = 4;
  93.  
  94. PROCEDURE UpdateSampleInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  95.  
  96. PROCEDURE TickSampleInfo;
  97.  
  98. PROCEDURE SampleAttr(s, a: BYTE);
  99.  
  100.  
  101.  
  102.  
  103. {----------------------------------------------------------------------------}
  104. { Definiciones para la ventana de osciloscopio.                              }
  105. {____________________________________________________________________________}
  106.  
  107. VAR
  108.   OscWinBuff    : ARRAY[1..16, 1..90*2] OF CHAR;
  109.   OscSamples    : ARRAY[1..360] OF INTEGER;
  110.  
  111. PROCEDURE UpdateOscilloscInfo;
  112.  
  113.  
  114.  
  115.  
  116. {----------------------------------------------------------------------------}
  117. { Definiciones para la ventana de canal on/off.                              }
  118. {____________________________________________________________________________}
  119.  
  120. VAR
  121.   DispPermisos   : ARRAY[1..16] OF BOOLEAN;
  122.  
  123. PROCEDURE UpdateOnOff;
  124.  
  125.  
  126.  
  127.  
  128. IMPLEMENTATION
  129.  
  130. USES SongUtils;
  131.  
  132. CONST
  133.   Channels : BYTE = 0;
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140. {----------------------------------------------------------------------------}
  141. { Implementación de la ventana de información de posición.                   }
  142. {____________________________________________________________________________}
  143.  
  144. PROCEDURE UpdateRunInfo(BPM, spd, patt, pos, seq, PSize: WORD);
  145.   CONST
  146.     s    : STRING   = '';
  147.     aon  : BYTE     = 0;
  148.     aoff : BYTE     = 0;
  149.   BEGIN
  150.  
  151.     WITH wRunInfo DO 
  152.       IF wTopLine.vis AND wTopLine.act THEN BEGIN
  153.         IF pos > 256 THEN pos := 1;
  154.         STR(seq   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+1), s);
  155.         STR(patt  : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+2), s);
  156.         STR(pos   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+3), s);
  157.         STR(PSize : 3, s); DirectWrite (ParseCoords(x+wriX2,   y+3), s);
  158.         STR(spd   : 3, s); DirectWrite (ParseCoords(x+wriX1,   y+4), s);
  159.         STR(BPM   : 3, s); DirectWrite (ParseCoords(x+wriX2,   y+4), s);
  160.  
  161.         IF (LastFilter    <> FilterIsOn) OR
  162.            (LastFilterOn  <> FilterOn)   OR
  163.            (LastFilterOff <> FilterOff)  OR wTopLine.forz THEN BEGIN
  164.           IF FilterIsOn THEN BEGIN
  165.             aon  := BYTE(col[4]);
  166.             aoff := BYTE(col[2]);
  167.           END ELSE BEGIN
  168.             aon  := BYTE(col[2]);
  169.             aoff := BYTE(col[4]);
  170.           END;
  171.           s[0] := #1;
  172.           s[1] := CHAR(ORD(FilterOn)  + ORD('0'));
  173.           DirectWriteAttr(ParseCoords(x+wriX2+5, y+4), s, aon);
  174.           s[1] := CHAR(ORD(FilterOff) + ORD('0'));
  175.           DirectWriteAttr(ParseCoords(x+wriX2+6, y+4), s, aoff);
  176.           LastFilter    := FilterIsOn;
  177.           LastFilterOn  := FilterOn;
  178.           LastFilterOff := FilterOff;
  179.         END;
  180.  
  181.       END;
  182.  
  183.   END;
  184.  
  185.  
  186.  
  187.  
  188. {----------------------------------------------------------------------------}
  189. { Implementación de las barras de vúmetros.                                  }
  190. {                                                                            }
  191. {   DL: Valor                                                                }
  192. {   DH: Primer cambiado                                                      }
  193. {   CH: Tamaño                                                               }
  194. {   ES:SI: Pantalla                                                          }
  195. {____________________________________________________________________________}
  196.  
  197. VAR
  198.   bararray : ARRAY[1..16] OF BYTE;
  199.   graybar  : ARRAY[1..16] OF BYTE;
  200.  
  201.  
  202. PROCEDURE MyWriteBar; ASSEMBLER;
  203.   ASM
  204.                 MOV     AL,[w2ndLine.act]
  205.                 AND     AL,[w2ndLine.vis]
  206.                 JZ      @@Fin
  207.  
  208.                 CMP     CH,32
  209.                 JC      @@ok
  210.                  MOV    CH,31
  211. @@ok:
  212.                 INC     CH
  213.                 SHR     CH,1
  214.                 INC     DH
  215.                 SHR     DH,1
  216.  
  217.                 MOV     DI,OFFSET bararray
  218.  
  219.                 MOV     AL,DH
  220.                 XOR     AH,AH
  221.  
  222.                 ADD     DI,AX
  223.                 ADD     SI,AX
  224.                 ADD     SI,AX
  225.                 SUB     CH,DH
  226.                 SUB     DL,DH
  227.                 SUB     DL,DH
  228.  
  229.                 TEST    DL,$80
  230.                 JNZ     @@nobar
  231.  
  232.                 PUSH    DX
  233.                 INC     DL
  234.                 SHR     DL,1
  235.                 CALL    @@dolp
  236.                 POP     DX
  237.                 TEST    DL,1
  238.                 JZ      @@nobar
  239.                 INC     [BYTE PTR ES:SI-2]
  240.  
  241. @@nobar:        MOV     DL,CH
  242.                 MOV     DI,OFFSET graybar
  243.  
  244. @@dolp:         OR      DL,DL
  245.                 JZ      @@Fin
  246.                 OR      CH,CH
  247.                 JZ      @@Fin
  248. @@lp:            MOV    AL,BarVal
  249.                  MOV    AH,[DI]
  250.                  MOV    [ES:SI],AX
  251.                  INC    SI
  252.                  INC    SI
  253.                  INC    DI
  254.                  DEC    CH
  255.                  JZ     @@Fin
  256.                  DEC    DL
  257.                  JNZ    @@lp
  258. @@Fin:
  259.   END;
  260.  
  261.  
  262.  
  263. PROCEDURE WriteBar(i: WORD); ASSEMBLER;
  264.   ASM
  265.         MOV     AX,i
  266.         DEC     AX
  267.         MOV     BX,OFFSET barlen
  268.         MOV     DI,OFFSET obarlen
  269.         ADD     BX,AX
  270.         ADD     DI,AX
  271.         MOV     DL,[BX]
  272.         MOV     CH,DL
  273.         MOV     DH,[DI]
  274.         CMP     CH,DH
  275.         JZ      @@Fin
  276.         JNC     @@ok
  277.          XCHG   DH,CH
  278. @@ok:
  279.         MOV     [DI],DL
  280.         AND     AL,15
  281.         MOV     SI,ScrSegment
  282.         CMP     SI,$A000
  283.         JC      @@Fin
  284.         MOV     ES,SI
  285.         MOV     SI,OFFSET barofs
  286.         ADD     SI,AX
  287.         ADD     SI,AX
  288.         MOV     SI,[SI]
  289.         CALL    MyWriteBar
  290. @@Fin:
  291.   END;
  292.  
  293.  
  294.  
  295.  
  296. PROCEDURE WriteBarForced(i: WORD); ASSEMBLER;
  297.   ASM
  298. {
  299. PUSH    DS
  300. MOV     AX,$B800
  301. MOV     DS,AX
  302. INC     [WORD PTR 4]
  303. POP     DS
  304. }
  305.         MOV     AX,i
  306.         DEC     AX
  307.         MOV     BX,OFFSET barlen
  308.         MOV     DI,OFFSET obarlen
  309.         ADD     BX,AX
  310.         ADD     DI,AX
  311.         MOV     DL,[BX]
  312.         MOV     [DI],DL
  313.         MOV     CH,32
  314.         MOV     DH,0
  315.         AND     AL,15
  316.         MOV     SI,ScrSegment
  317.         CMP     SI,$A000
  318.         JC      @@Fin
  319.         MOV     ES,SI
  320.         MOV     SI,OFFSET barofs
  321.         ADD     SI,AX
  322.         ADD     SI,AX
  323.         MOV     SI,[SI]
  324.         CALL    MyWriteBar
  325. @@Fin:
  326.   END;
  327.  
  328.  
  329.  
  330.  
  331. PROCEDURE InitBar(i, l: WORD);
  332.   BEGIN
  333.     IF l > 32 THEN l := 32;
  334.     barlen[i] := l+1;
  335.     IF Permisos[i] THEN
  336.       IF w2ndLine.forz THEN
  337.         WriteBarForced(i)
  338.       ELSE
  339.         WriteBar(i);
  340.   END;
  341.  
  342.  
  343.  
  344. PROCEDURE UpdateBars;
  345.   CONST
  346.     i : WORD = 0;
  347.   BEGIN
  348.     FOR i := 1 TO 16{MaxChannels} DO
  349.       BEGIN
  350.         IF NOT Permisos[i] THEN barlen[i] := 0;
  351.         IF barlen[i] > 0 THEN
  352.           DEC(barlen[i]);
  353.         IF w2ndLine.act AND w2ndLine.vis THEN
  354.           IF w2ndLine.forz THEN
  355.             WriteBarForced(i)
  356.           ELSE
  357.             WriteBar(i)
  358.       END;
  359.   END;
  360.  
  361.  
  362.  
  363.  
  364.  
  365. PROCEDURE ParseBarInit(VAR nt: TFullNote; i: WORD);
  366.   BEGIN
  367.  
  368.     IF      nt.Command     = mcSetVolume THEN InitBar(i, nt.Parameter      SHR 1)
  369.     ELSE IF nt.Instrument <> 0           THEN InitBar(i, Canales[i].Volume SHR 1)
  370.     ELSE IF nt.Period     <> 0           THEN InitBar(i, RealVolumes[i]    SHR 1);
  371.  
  372.   END;
  373.  
  374.  
  375.  
  376.  
  377. {----------------------------------------------------------------------------}
  378. { Implementación de las ventanas de información de notas.                    }
  379. {____________________________________________________________________________}
  380.  
  381. PROCEDURE UpdateNoteInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  382.   CONST
  383.     s        : STRING         = '';
  384.     MySample : BYTE           = 0;
  385.     vol      : WORD           = 0;
  386.     f        : BOOLEAN        = FALSE;
  387.     p        : PFullNote      = NIL;
  388.     Instr    : PInstrumentRec = NIL;
  389.   BEGIN
  390.     Channels := Song.NumChannels;
  391.  
  392.     IF w2ndLine.forz AND w2ndLine.vis AND w2ndLine.act AND (i <= 16) THEN
  393.       BEGIN
  394.         STR(i : 2, s);
  395.         WITH wChannelNum DO
  396.           DirectWrite(ParseCoords(x+1, y+i), s);
  397.  
  398.         IF NOT PlayMod.Permisos[i] THEN
  399.           BEGIN
  400.             WITH wInfoNote  DO DirectWrite(ParseCoords(x+1, y+i), '                            ');
  401.             WITH wRunSample DO DirectWrite(ParseCoords(x+1, y+i), '                        ');
  402.           END;
  403.       END;
  404.  
  405.     p := @DispNotes[i];
  406.  
  407.     WITH RealNotes[i] DO BEGIN
  408.  
  409.       IF (nt.Period <> Period) AND (nt.Period <> 0) THEN
  410.         Period := nt.Period
  411.       ELSE
  412.         Period := p^.Period;
  413.  
  414.       IF (nt.Instrument <> Instrument) AND (nt.Instrument <> 0) THEN
  415.         Instrument := nt.Instrument
  416.       ELSE
  417.         Instrument := p^.Instrument;
  418.  
  419.       vol := $FFFF;
  420.  
  421.       IF (nt.Period <> 0) OR (nt.Instrument <> 0) THEN vol := Canales[i].Volume;
  422.       IF nt.Command = mcSetVolume THEN vol := nt.Parameter;
  423.  
  424.       IF (vol <> $FFFF) AND (vol <> RealVolumes[i]) THEN
  425.         RealVolumes[i] := vol
  426.       ELSE
  427.         vol := RealVolumes[i];
  428.  
  429.       IF w2ndLine.act AND w2ndLine.vis AND PlayMod.Permisos[i] THEN BEGIN
  430.         IF w2ndLine.forz OR (p^.Period <> Period) THEN BEGIN
  431.           IF Period <> 0 THEN
  432.             BEGIN
  433.               p^.Period := Period;
  434.  
  435.               IF i <= 16 THEN
  436.                 BEGIN
  437.                   NoteFreq(Period, s);
  438.                   WITH wInfoNote DO DirectWrite(ParseCoords(x+winX1, y+i), s);
  439.                 END;
  440.             END;
  441.         END;
  442.  
  443.         IF w2ndLine.forz OR (Instrument <> p^.Instrument) THEN BEGIN
  444.           p^.Instrument := Instrument;
  445.           IF i <= 16 THEN
  446.             WITH wInfoNote DO
  447.               BEGIN
  448.                 Instr := PInstrument(Song.GetInstrument(p^.Instrument))^.Instr;
  449.                 IF Instr <> NIL THEN
  450.                   BEGIN
  451.                     STR(Instr^.reps : 6, s); DirectWrite(ParseCoords(x+winX3, y+i), s);
  452.                     STR(Instr^.repl : 6, s); DirectWrite(ParseCoords(x+winX4, y+i), s);
  453.                     STR(Instr^.len  : 6, s); DirectWrite(ParseCoords(x+winX5, y+i), s);
  454.                   END
  455.                 ELSE
  456.                   BEGIN
  457.                     DirectWrite(ParseCoords(x+winX3, y+i), '      ');
  458.                     DirectWrite(ParseCoords(x+winX4, y+i), '      ');
  459.                     DirectWrite(ParseCoords(x+winX5, y+i), '     ');
  460.                   END;
  461.               END;
  462.         END;
  463.  
  464.         IF w2ndLine.forz OR (Instrument <> DispSplName[i]) THEN BEGIN
  465.           DispSplName[i]   := Instrument;
  466.           IF i <= 16 THEN
  467.             WITH wRunSample DO
  468.               IF Instrument <> 0 THEN
  469.                 DirectWrite(ParseCoords(x+1, y+i), SampleStrings[Instrument])
  470.               ELSE
  471.                 DirectWrite(ParseCoords(x+1, y+i), '                        ');
  472.         END;
  473.  
  474.         IF w2ndLine.forz OR (DispVolumes[i] <> vol) THEN BEGIN
  475.           DispVolumes[i]   := vol;
  476.           IF i <= 16 THEN
  477.             WITH wInfoNote DO
  478.               IF DispVolumes[i] <> $FF THEN
  479.                 DirectWrite(ParseCoords(x+winX2, y+i), VolumeStrings[vol])
  480.               ELSE
  481.                 DirectWrite(ParseCoords(x+winX2, y+i), '  ');
  482.         END;
  483.  
  484.       END;
  485.     END;
  486.   END;
  487.  
  488.  
  489.  
  490.  
  491. PROCEDURE SampleAttr(s, a: BYTE);
  492.   BEGIN
  493.     IF s > 60 THEN EXIT;
  494.  
  495.     IF s > 40 THEN
  496.       WITH wSamples3 DO RectAttr(ParseCoords(x+wsX1, y+s-40), 25, 1, a)
  497.     ELSE IF s > 20 THEN
  498.       WITH wSamples2 DO RectAttr(ParseCoords(x+wsX1, y+s-20), 25, 1, a)
  499.     ELSE
  500.       WITH wSamples1 DO RectAttr(ParseCoords(x+wsX1, y+s),    25, 1, a);
  501.   END;
  502.  
  503.  
  504.  
  505.  
  506. PROCEDURE UpdateSampleInfo(VAR Song: TSong; VAR nt: TFullNote; i: WORD);
  507.   CONST
  508.     j      : WORD = 0;
  509.   LABEL
  510.     Passa;
  511.   BEGIN                 
  512.     IF i = 1 THEN BEGIN
  513.       FOR j := 1 TO 60 DO
  514.         IF RealSamples[j] >= sfNowUsed THEN
  515.           RealSamples[j] := sfUsed;
  516.     END;
  517.  
  518.     IF Permisos[i] AND (RealNotes[i].Instrument <> 0) THEN
  519.       IF (nt.Instrument <> 0) OR (nt.Period <> 0) OR ((nt.Command = mcSetVolume) AND (nt.Parameter <> 0)) THEN
  520.         RealSamples[RealNotes[i].Instrument] := sfFlashing
  521.       ELSE
  522.         IF RealSamples[RealNotes[i].Instrument] <> sfFlashing THEN
  523.           RealSamples[RealNotes[i].Instrument] := sfNowUsed;
  524.  
  525.     IF i = Song.NumChannels THEN BEGIN
  526. {
  527.       siCounter := NoteSound^.Tempo-1;
  528.       IF siCounter < 2 THEN siCounter := 2;
  529. }
  530. siCounter := 0;
  531.  
  532.       WITH wSamples DO BEGIN
  533.         siPermiso := act AND vis;
  534.  
  535.         IF siPermiso AND forz THEN BEGIN
  536. {          InitSampleWin(Song);}
  537.           siTickForce := forz;
  538. {          TickSampleInfo;}
  539.         END;
  540.  
  541.         forz := FALSE;
  542.       END;
  543.     END;
  544.   END;
  545.  
  546.  
  547.  
  548.  
  549. PROCEDURE TickSampleInfo;
  550.   CONST
  551.     i  : WORD = 0;
  552.     vl : BYTE = 0;
  553.   BEGIN
  554.     WITH wSamples DO 
  555.       IF NOT (act AND vis) THEN EXIT;
  556.  
  557.     INC(siCounter);
  558.  
  559.     FOR i := 1 TO 60 DO BEGIN
  560.       vl := RealSamples[i];
  561.       IF (siCounter > NoteSound^.Tempo) AND (vl = sfFlashing) THEN
  562.         BEGIN
  563.           vl             := sfNowUsed;
  564.           RealSamples[i] := sfNowUsed;
  565.         END;
  566.  
  567.       IF (vl > sfNoSample) AND ((vl <> DispSamples[i]) OR siTickForce) THEN
  568.         BEGIN
  569.           DispSamples[i] := vl;
  570.  
  571.           IF siPermiso THEN
  572.             SampleAttr(i, BYTE(wSamples.col[vl+4]));
  573.         END;
  574.     END;
  575.  
  576.     siTickForce := FALSE;
  577.  
  578.   END;
  579.  
  580.  
  581.  
  582.  
  583. PROCEDURE UpdateOnOff;
  584.   CONST
  585.     Strn : ARRAY[0..1] OF STRING[3] = ('OFF', 'ON ');
  586.     i    : WORD = 0;
  587.   BEGIN
  588.     IF w2ndLine.act AND w2ndLine.vis THEN
  589.       FOR i := 1 TO 16 DO
  590.         IF i > Channels THEN
  591.           BEGIN
  592.             DispPermisos[i] := FALSE;
  593.             WITH wVoiceOnOff DO DirectWrite(ParseCoords(x+1, y+i), Strn[0]);
  594.           END
  595.         ELSE IF w2ndLine.forz OR (Permisos[i] <> DispPermisos[i]) THEN
  596.           BEGIN
  597.             DispPermisos[i] := Permisos[i];
  598.             WITH wVoiceOnOff DO DirectWrite(ParseCoords(x+1, y+i), Strn[ORD(Permisos[i])]);
  599.           END;
  600.   END;
  601.  
  602.  
  603.  
  604.  
  605. PROCEDURE Update2ndLine(VAR Song: TSong; NewNote: BOOLEAN);
  606.   VAR
  607.     i : WORD;
  608.   BEGIN
  609.  
  610.     UpdateOnOff;
  611.     UpdateBars;
  612.  
  613.     IF w2ndLine.forz AND w2ndLine.act AND w2ndLine.vis THEN
  614.       WITH wPanning DO BEGIN
  615.         FOR i := 1 TO 16 DO
  616.           IF Song.PanPositions[i] < $80 THEN
  617.             DirectWriteAttr(ParseCoords(x+1, y+i), '⌡÷⌡⌡⌡⌡', BYTE(col[1]))
  618.           ELSE
  619.             DirectWriteAttr(ParseCoords(x+1, y+i), '⌡⌡⌡⌡≈⌡', BYTE(col[1]));
  620.       END;
  621.  
  622.     IF NewNote THEN
  623.       w2ndLine.forz := FALSE;
  624.  
  625.   END;
  626.  
  627.  
  628.  
  629.  
  630. PROCEDURE PutStr(VAR Buf; VAR s: STRING; c: BYTE);
  631.   CONST
  632.     i : WORD = 0;
  633.   VAR
  634.     CBuf : ARRAY[1..32000, 1..2] OF BYTE ABSOLUTE Buf;
  635.   BEGIN
  636.  
  637.     FOR i := 1 TO Length(s) DO BEGIN
  638.       CBuf[i][1] := BYTE(s[i]);
  639.       CBuf[i][2] := c;
  640.     END;
  641.  
  642.   END;
  643.  
  644.  
  645.  
  646.  
  647. {
  648. PROCEDURE FillWithSamples(VAR Buff; Size: WORD);
  649.   VAR
  650.     mBuff : ARRAY[0..FinalBufferSize-1] OF INTEGER ABSOLUTE Buff;
  651.   BEGIN
  652.     IF FinalBufferPos >= Size THEN
  653.       Move(FinalBuffer[FinalBufferPos - Size], mBuff, Size*2)
  654.     ELSE
  655.       Move(FinalBuffer[FinalBufferSize - Size], mBuff, Size*2)
  656.   END;
  657. }
  658.  
  659.  
  660. PROCEDURE UpdateOscilloscInfo;
  661.   CONST
  662.     Count    : WORD = 0;
  663.     Semaphor : BYTE = 0;
  664.     i        : WORD = 0;
  665.     j        : WORD = 0;
  666.     ofs      : WORD = 0;
  667.   LABEL
  668.     Fin;
  669.   BEGIN
  670.     IF Semaphor > 0 THEN EXIT;
  671.  
  672.     INC(Semaphor);
  673.  
  674.     WITH wOscillosc DO BEGIN
  675.       IF NOT (act AND vis) THEN GOTO Fin;
  676.  
  677.       INC(Count);
  678.       IF Count < 1 THEN GOTO Fin;
  679.  
  680.       Count := 0;
  681.  
  682.       IF UsingGUS THEN
  683.         BEGIN
  684.           IF forz THEN
  685.             DirectWriteAttr(ParseCoords(x+1, y+9), GetString(StrGUSOscillosc), BYTE(col[1]));
  686.           GOTO Fin;
  687.         END;
  688.  
  689.       FillWithSamples(OscSamples, 82*4);
  690.  
  691.       ASM
  692.         CLD
  693.         MOV     CX,16
  694.         MOV     DI,OFFSET OscWinBuff + 8
  695.         PUSH    DS
  696.         POP     ES
  697.         MOV     DX,90*2 - 82*2
  698.         MOV     AH,BYTE PTR [wOscillosc.col[2]]
  699.         XOR     AL,AL
  700. @@lp1:   PUSH   CX
  701.          MOV    CX,82
  702.          REP STOSW
  703.          POP    CX
  704.          ADD    DI,DX
  705.          LOOP   @@lp1
  706.       END;
  707.       ASM
  708.  
  709.         CLD
  710.         MOV     CH,82
  711.         MOV     SI,OFFSET OscSamples
  712.         MOV     BX,OFFSET OscWinBuff + 8
  713. @@lp1:   MOV    CL,4
  714. @@lp2:    LODSW
  715.           XOR   AH,$80
  716.  
  717.           XOR   DX,DX
  718.           MOV   DI,65536/16/3 - 1
  719.           DIV   DI
  720.  
  721.           MOV   DL,3
  722.           DIV   DL
  723.           MOV   DL,AH
  724.           INC   DL
  725.  
  726.           MOV   DI,CX
  727.           DEC   CL
  728.           ADD   CL,CL
  729.           SHL   DL,CL
  730.           MOV   CX,DI
  731.  
  732.           MOV   DH,90*2
  733.           MUL   DH
  734.           ADD   AX,BX
  735.           XCHG  BX,AX
  736.           ADD   [BX],DL
  737.           XCHG  BX,AX
  738.  
  739.           DEC   CL
  740.           JNZ   @@lp2
  741.          INC    BX
  742.          INC    BX
  743.          DEC    CH
  744.          JNZ    @@lp1
  745.  
  746.       END;
  747.  
  748.       Ofs := ParseCoords(x+4, y+3);
  749.       FOR i := 1 TO 16 DO BEGIN
  750.         Move(OscWinBuff[i][9], Ptr(ScrSegment, Ofs)^, 82*2);
  751.         INC(Ofs, ScreenBytesX);
  752.       END;
  753.  
  754.     END;
  755.  
  756. Fin:
  757.     wOscillosc.forz := FALSE;
  758.  
  759.     DEC(Semaphor);
  760.  
  761.   END;
  762.  
  763.  
  764.  
  765.  
  766. PROCEDURE InitPlayData(VAR Song: TSong);
  767.   CONST
  768.     i     : WORD           = 0;
  769.     j     : WORD           = 0;
  770.     Instr : PInstrumentRec = NIL;
  771.   BEGIN
  772.  
  773.     LastFilterOn  := fmNone;
  774.     LastFilterOff := fmNone;
  775.     LastFilter    := FALSE;
  776.  
  777.     FillChar(barlen,  SizeOf(barlen),  0);
  778.     FillChar(Obarlen, SizeOf(Obarlen), 0);
  779.     FillChar(graybar, SizeOf(graybar), wPlayBars.col[1]);
  780.     WITH wPlayBars DO BEGIN
  781.       FOR i := 1 TO 16 DO
  782.         BEGIN
  783.           barofs[i]   := ParseCoords(wPlayBars.x + 1, wPlayBars.y + i);
  784.           IF i < 13 THEN
  785.             bararray[i] := BYTE(col[2])
  786.           ELSE
  787.             bararray[i] := BYTE(col[3]);
  788.         END;
  789.       forz := TRUE;
  790.       act  := TRUE;
  791.       vis  := TRUE;
  792.     END;
  793.  
  794.     FOR i := 0 TO 64 DO
  795.       STR(i : 2, VolumeStrings[i]);
  796.  
  797.     FillChar(DispVolumes, SIZEOF(DispVolumes), $FF);
  798.     FillChar(DispNotes,   SIZEOF(DispNotes),   0);
  799.     FillChar(RealVolumes, SIZEOF(RealVolumes), $FF);
  800.     FillChar(RealNotes,   SIZEOF(RealNotes),   0);
  801.  
  802.     FillChar(DispSplName, SIZEOF(DispSplName), 0);
  803.  
  804.     FillChar(DispSamples, SIZEOF(DispSamples), sfNoSample);
  805.     FillChar(RealSamples, SIZEOF(RealSamples), sfNoSample);
  806.  
  807.     IF @Song <> NIL THEN
  808.       FOR i := 1 TO Song.Instruments.Count DO BEGIN
  809.         STR(i : 2, SampleStrings[i]);
  810.         SampleStrings[i] := SampleStrings[i] + ' ' + Song.GetInstrument(i)^.GetName;
  811.         Instr := Song.GetInstrument(i)^.Instr;
  812.         IF (Instr <> NIL) AND (Instr^.Len <> 0) THEN
  813.           BEGIN
  814.             DispSamples[i] := sfNotUsed;
  815.             RealSamples[i] := sfNotUsed;
  816.           END;
  817.       END;
  818.  
  819.     siTickForce    := FALSE;
  820.     siPermiso      := TRUE;
  821.     siCounter      := 0;
  822.  
  823.     FillChar(DispPermisos, SIZEOF(DispPermisos), 0);
  824.   END;
  825.  
  826.  
  827.  
  828.  
  829.  
  830. END.
  831.